Use CommandExt::exec for `cargo run` on Unix (#2343)
authorRobin Stocker <robin@nibor.org>
Fri, 1 Jul 2016 04:31:36 +0000 (14:31 +1000)
committerRobin Stocker <robin@nibor.org>
Thu, 20 Oct 2016 02:07:52 +0000 (13:07 +1100)
Before, we would spawn a child process for the program. One of the
problems with that is when killing the cargo process, the program
continues running.

With this change, the cargo process is replaced by the program, and
killing it works.

src/cargo/ops/cargo_run.rs
src/cargo/util/process_builder.rs
tests/run.rs

index 34c28dbc4cbb8b3ee364fbe77d3fe9e7311b3bca..897a3da5116820ed57b8bc2de5eb8470f587130d 100644 (file)
@@ -52,5 +52,5 @@ pub fn run(ws: &Workspace,
     process.args(args).cwd(config.cwd());
 
     try!(config.shell().status("Running", process.to_string()));
-    Ok(process.exec().err())
+    Ok(process.exec_replace().err())
 }
index c0d88d2ae8603b81d523a01dd3cd44d8efe9c179..b66b26ec0a4ee6bb021ffa9f42b6c051916a9d80 100644 (file)
@@ -89,6 +89,22 @@ impl ProcessBuilder {
         }
     }
 
+    #[cfg(unix)]
+    pub fn exec_replace(&self) -> Result<(), ProcessError> {
+        use std::os::unix::process::CommandExt;
+
+        let mut command = self.build_command();
+        let error = command.exec();
+        Err(process_error(&format!("could not execute process `{}`",
+                                   self.debug_string()),
+                          Some(Box::new(error)), None, None))
+    }
+
+    #[cfg(windows)]
+    pub fn exec_replace(&self) -> Result<(), ProcessError> {
+        self.exec()
+    }
+
     pub fn exec_with_output(&self) -> Result<Output, ProcessError> {
         let mut command = self.build_command();
 
index 7c769c2451506557ee513ab699c9895889ace842..eb438ac417069014c60b0674b368ae02a7690756 100644 (file)
@@ -126,14 +126,18 @@ fn exit_code() {
             fn main() { std::process::exit(2); }
         "#);
 
-    assert_that(p.cargo_process("run"),
-                execs().with_status(2)
-                       .with_stderr("\
+    let mut output = String::from("\
 [COMPILING] foo v0.0.1 (file[..])
 [FINISHED] debug [unoptimized + debuginfo] target(s) in [..]
 [RUNNING] `target[..]`
+");
+    if !cfg!(unix) {
+        output.push_str("\
 [ERROR] process didn't exit successfully: `target[..]foo[..]` (exit code: 2)
-"));
+");
+    }
+    assert_that(p.cargo_process("run"),
+                execs().with_status(2).with_stderr(output));
 }
 
 #[test]
@@ -149,15 +153,20 @@ fn exit_code_verbose() {
             fn main() { std::process::exit(2); }
         "#);
 
-    assert_that(p.cargo_process("run").arg("-v"),
-                execs().with_status(2)
-                       .with_stderr("\
+    let mut output = String::from("\
 [COMPILING] foo v0.0.1 (file[..])
 [RUNNING] `rustc [..]`
 [FINISHED] debug [unoptimized + debuginfo] target(s) in [..]
 [RUNNING] `target[..]`
+");
+    if !cfg!(unix) {
+        output.push_str("\
 [ERROR] process didn't exit successfully: `target[..]foo[..]` (exit code: 2)
-"));
+");
+    }
+
+    assert_that(p.cargo_process("run").arg("-v"),
+                execs().with_status(2).with_stderr(output));
 }
 
 #[test]